package br.com.foxinline.manager.utilitario;

import br.com.foxinline.enums.Banco;
import br.com.foxinline.enums.Caracterizacao;
import br.com.foxinline.enums.Cobertura;
import br.com.foxinline.enums.Comando;
import br.com.foxinline.enums.ComposicaoFamiliar;
import br.com.foxinline.enums.DominioTerra;
import br.com.foxinline.enums.EstadoCivil;
import br.com.foxinline.enums.EstadoConservacao;
import br.com.foxinline.enums.Estrutura;
import br.com.foxinline.enums.Fachada;
import br.com.foxinline.enums.FatorLocalizacao;
import br.com.foxinline.enums.Forro;
import br.com.foxinline.enums.InstSanitaria;
import br.com.foxinline.enums.InstalacoesEletricas;
import br.com.foxinline.enums.Ocupacao;
import br.com.foxinline.enums.Patrimonio;
import br.com.foxinline.enums.Pedologia;
import br.com.foxinline.enums.Piso;
import br.com.foxinline.enums.Posicao;
import br.com.foxinline.enums.RendaFamiliar;
import br.com.foxinline.enums.RevExterno;
import br.com.foxinline.enums.SaneamentoBasico;
import br.com.foxinline.enums.SistemaAgua;
import br.com.foxinline.enums.SituacaoImovel;
import br.com.foxinline.enums.SituacaoTerreno;
import br.com.foxinline.enums.StatusColetaDados;
import br.com.foxinline.enums.TipoAnexo;
import br.com.foxinline.enums.TipoConstrucao;
import br.com.foxinline.enums.TipoDocumento;
import br.com.foxinline.enums.TipoDocumentoImovel;
import br.com.foxinline.enums.TipoImovel;
import br.com.foxinline.enums.TipoPavimentacao;
import br.com.foxinline.enums.TipoQualidade;
import br.com.foxinline.enums.TipoRequerimento;
import br.com.foxinline.enums.Topografia;
import br.com.foxinline.enums.UsoImovel;
import br.com.foxinline.enums.Utilizacao;
import br.com.foxinline.enums.Vinculo;
import br.com.foxinline.modelo.*;
import br.com.foxinline.servico.AforamentoServico;
import br.com.foxinline.servico.AnexoServico;
import br.com.foxinline.servico.AverbacaoServico;
import br.com.foxinline.servico.BairroServico;
import br.com.foxinline.servico.CidadeServico;
import br.com.foxinline.servico.DneServico;
import br.com.foxinline.servico.EstadoServico;
import br.com.foxinline.servico.ImovelServico;
import br.com.foxinline.servico.LocalidadeServico;
import br.com.foxinline.servico.PrefeituraServico;
import br.com.foxinline.servico.ProprietarioServico;
import br.com.foxinline.servico.QuadraServico;
import br.com.foxinline.servico.SetorServico;
import br.com.foxinline.servico.UsuarioServico;
import br.com.foxinline.util.Caracter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;

/**
 *
 * @author laverson
 */
@ViewScoped
@ManagedBean
public class ManagerUtilitario {

    @EJB
    AverbacaoServico averbacaoServico;
    @EJB
    EstadoServico estadoServico;
    @EJB
    CidadeServico cidadeServico;
    @EJB
    BairroServico bairroServico;
    @EJB
    SetorServico setorServico;
    @EJB
    UsuarioServico usuarioServico;
    @EJB
    QuadraServico quadraServico;
    @EJB
    ImovelServico imovelServico;
    @EJB
    ProprietarioServico proprietarioServico;
    @EJB
    DneServico dneServico;
    @EJB
    AnexoServico anexoServico;
    @EJB
    AforamentoServico aforamentoServico;
    @EJB
    LocalidadeServico localidadeServico;
    @EJB
    PrefeituraServico prefeituraServico;
    private Cidade cidade;
    private Endereco endereco;
    private Estado estado;

    @PostConstruct
    public void init() {
        Prefeitura prefeitura = prefeituraServico.find();

        if (prefeitura != null) {
            Endereco e = prefeitura.getEndereco();

            if (e != null) {
                Bairro bairro = e.getBairroDne();

                if (bairro != null) {
                    Cidade c = bairro.getCidade();

                    if (c != null) {
                        Estado es = c.getEstado();

                        this.cidade = c;
                        this.estado = es != null ? es : null;
                    }
                }
            }
        }
    }

    public boolean instanceOfString(Object object) {
        return object instanceof String;
    }

    public boolean instanceOfInteger(Object object) {
        return object instanceof Integer;
    }

    public boolean instanceOfBoolean(Object object) {
        return object instanceof Boolean;
    }

    public boolean instanceOfDouble(Object object) {
        return object instanceof Double;
    }

    public boolean instanceOfBigDecimal(Object object) {
        return object instanceof BigDecimal;
    }

    public boolean instanceOfCidade(Object object) {
        if (object instanceof Cidade) {
            cidade = (Cidade) object;
            return true;
        }

        return false;
    }

    public boolean instanceOfEndereco(Object object) {
        if (object instanceof Endereco) {
            endereco = (Endereco) object;
        }

        return false;
    }

    public boolean instanceOfProprietario(Object object) {

        if (object instanceof List && !((List) object).isEmpty() && ((List) object).get(0) instanceof Proprietario) {
            return true;
        }

        return object instanceof Proprietario;
    }

    public boolean instanceOfAnexo(Object object) {

        if (object instanceof List && !((List) object).isEmpty() && ((List) object).get(0) instanceof Anexo) {
            return true;
        }

        return object instanceof Anexo;
    }

    public boolean instanceOfEnum(Object object) {
        return object instanceof Enum;
    }

    public String proprietarios(Object object) {

        String nomes = "";

        if (instanceOfProprietario(object)) {

            List<Proprietario> proprietarios = (List<Proprietario>) object;

            nomes = averbacaoServico.getNomeProprietarios(proprietarios);
        }

        return nomes;
    }

    public String anexos(Object object) {

        String nomes = "";

        if (instanceOfAnexo(object)) {

            List<Anexo> anexos = (List<Anexo>) object;

            for (Anexo anexo : anexos) {
                nomes += anexo.getNomeExibicao() + "\n";
            }
        }

        return nomes;
    }

    public Cidade getCidade() {
        return cidade;
    }

    public void setCidade(Cidade cidade) {
        this.cidade = cidade;
    }

    public Endereco getEndereco() {
        return endereco;
    }

    public void setEndereco(Endereco endereco) {
        this.endereco = endereco;
    }

    public Estado getEstado() {
        return estado;
    }

    public void setEstado(Estado estado) {
        this.estado = estado;
    }

    public String mascaraCPF(String cpf) {
        if (cpf != null && !cpf.isEmpty()) {
            return Caracter.addMask(cpf, Caracter.cpfMask);
        }

        return "-";
    }

    public String mascaraCNPJ(String cnpj) {
        if (cnpj != null && !cnpj.isEmpty()) {
            return Caracter.addMask(cnpj, Caracter.cnpjMask);
        }

        return "-";
    }

    public List<SelectItem> getBancos() {
        List<SelectItem> items = new ArrayList<SelectItem>();
        for (Banco banco : Banco.values()) {
            items.add(new SelectItem(banco, banco.getNome()));
        }
        return items;
    }

    public List<SelectItem> getSetor() {
        List<SelectItem> items = new ArrayList<SelectItem>();
        List<Setor> setores = setorServico.findAll();

        for (Setor item : setores) {
            items.add(new SelectItem(item, item.getNumero().toString()));
        }
        return items;
    }

    public List<SelectItem> getStatusColetaDados() {
        List<SelectItem> items = new ArrayList<SelectItem>();
        for (StatusColetaDados item : StatusColetaDados.values()) {
            items.add(new SelectItem(item, item.getNome()));
        }
        return items;
    }

    public List<SelectItem> getQuadra(Setor setor) {
        List<SelectItem> items = new ArrayList<SelectItem>();
        List<Quadra> quadras = quadraServico.find(setor);

        for (Quadra item : quadras) {
            items.add(new SelectItem(item, item.getNumero().toString()));
        }
        return items;
    }

    public List<SelectItem> getEstadoCivil() {
        List<SelectItem> items = new ArrayList<SelectItem>();

        for (EstadoCivil item : EstadoCivil.values()) {
            items.add(new SelectItem(item, item.getNome()));
        }
        return items;
    }

    public List<SelectItem> getFatorLocalizacao() {
        List<SelectItem> items = new ArrayList<SelectItem>();

        for (FatorLocalizacao item : FatorLocalizacao.values()) {
            items.add(new SelectItem(item, item.getNome()));
        }
        return items;
    }

    public List<SelectItem> getTipoAnexo() {
        List<SelectItem> items = new ArrayList<SelectItem>();

        for (TipoAnexo item : TipoAnexo.values()) {
            items.add(new SelectItem(item, item.getNome()));
        }
        return items;
    }

    public List<SelectItem> getComposicaoFamiliar() {
        List<SelectItem> items = new ArrayList<SelectItem>();

        for (ComposicaoFamiliar item : ComposicaoFamiliar.values()) {
            items.add(new SelectItem(item, item.getNome()));
        }
        return items;
    }

    public List<SelectItem> getRendaFamiliar() {
        List<SelectItem> items = new ArrayList<SelectItem>();

        for (RendaFamiliar item : RendaFamiliar.values()) {
            items.add(new SelectItem(item, item.getNome()));
        }
        return items;
    }

    public List<SelectItem> getTipoPavimentacao() {
        List<SelectItem> items = new ArrayList<SelectItem>();

        for (TipoPavimentacao item : TipoPavimentacao.values()) {
            items.add(new SelectItem(item, item.getNome()));
        }
        return items;
    }

    public List<SelectItem> tipoDocumentoList() {
        List<SelectItem> items = new ArrayList<SelectItem>();
        for (TipoDocumento item : TipoDocumento.values()) {
            items.add(new SelectItem(item.getTipo(), item.getNome()));
        }
        return items;
    }

    public List<SelectItem> getComando() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Comando item : Comando.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getOcupacao() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Ocupacao item : Ocupacao.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getTopografia() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Topografia item : Topografia.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getSituacaoTerreno() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (SituacaoTerreno item : SituacaoTerreno.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getPedologia() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Pedologia item : Pedologia.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getUtilizacao() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Utilizacao item : Utilizacao.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getPatrimonioList() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Patrimonio item : Patrimonio.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getUsoImovel() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (UsoImovel item : UsoImovel.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getCaracterizacao() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Caracterizacao item : Caracterizacao.values()) {
            if (!item.equals(Caracterizacao.EM_BRANCO)) {
                s.add(new SelectItem(item, item.getNome()));
            }
        }
        return s;
    }

    public List<SelectItem> getRevExterno() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (RevExterno item : RevExterno.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getVinculoTitularRip() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Vinculo item : Vinculo.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getPiso() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Piso item : Piso.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getForro() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Forro item : Forro.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getCobertura() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Cobertura item : Cobertura.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getInstSanitaria() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (InstSanitaria item : InstSanitaria.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getPosicao() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Posicao item : Posicao.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getTipoDocumentoImovel() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (TipoDocumentoImovel item : TipoDocumentoImovel.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getTipoConstrucao() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (TipoConstrucao item : TipoConstrucao.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getDominioTerra() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (DominioTerra item : DominioTerra.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getEstrutura() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Estrutura item : Estrutura.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getEstadoConservacao() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (EstadoConservacao item : EstadoConservacao.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getInstalacoesEletrica() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (InstalacoesEletricas item : InstalacoesEletricas.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getFachada() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (Fachada item : Fachada.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getTipoImovel() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (TipoImovel item : TipoImovel.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getSituacaoImovel() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (SituacaoImovel item : SituacaoImovel.values()) {
            if (!item.equals(SituacaoImovel.EM_BRANCO)) {
                s.add(new SelectItem(item, item.getNome()));
            }
        }
        return s;
    }

    public List<SelectItem> getSistemaAgua() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (SistemaAgua item : SistemaAgua.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getSaneamentoBasico() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (SaneamentoBasico item : SaneamentoBasico.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getTipoDocumento() {
        List<SelectItem> s = new ArrayList<SelectItem>();
        for (TipoDocumento item : TipoDocumento.values()) {
            s.add(new SelectItem(item, item.getNome()));
        }
        return s;
    }

    public List<SelectItem> getTipoQualidade() {
        List<SelectItem> items = new ArrayList<SelectItem>();
        for (TipoQualidade item : TipoQualidade.values()) {
            items.add(new SelectItem(item, item.getName()));
        }
        return items;
    }

    public List<SelectItem> getTipoRequerimento() {
        List<SelectItem> items = new ArrayList<SelectItem>();
        for (TipoRequerimento item : TipoRequerimento.values()) {
            items.add(new SelectItem(item, item.getName()));
        }
        return items;
    }

    public List<Estado> autocompleteEstado(String query) {
        return estadoServico.autocomplete(query);
    }

    /**
     * Este método requer que o field 'estado' esteja setado, pois a consulta será de acordo com o 'estado' selecionado
     *
     * @param query
     * @return
     */
    public List<Cidade> autocompleteCidadePorEstado(String query) {
        return cidadeServico.autocomplete(query, this.estado);
    }

    public List<Cidade> autocompleteCidade(String query) {
        return cidadeServico.autocomplete(query);
    }

    /**
     * Este método requer que o field 'cidade' esteja setado, pois a consulta será de acordo com a 'cidade' selecionada
     *
     * @param query
     * @return
     */
    public List<Bairro> autocompleteBairroPorCidade(String query) {
        return bairroServico.autocomplete(query, this.cidade);
    }

    public List<Bairro> autocompleteBairro(String query) {
        return bairroServico.autocomplete(query);
    }

    public List<Setor> autocompleteSetor(String query) {
        return setorServico.autocomplete(query);
    }

    public List<Usuario> autocompleteUsuario(String query) {
        return usuarioServico.autocomplete(query);
    }

    public List<Proprietario> autocompletePessoaFisica(String query) {
        return proprietarioServico.autocompletePessoaFisica(query);
    }

    public List<Proprietario> autocompletePessoaJuridica(String query) {
        return proprietarioServico.autocompletePessoaJuridica(query);
    }

    public List<Proprietario> autocompletePessoa(String query) {
        return proprietarioServico.autocompletePessoa(query);
    }

    public List<Dne> autocompleteDne(String query) {
        return dneServico.autocomplete(query, null);
    }

    public String inscricaoCadastral(Imovel imovel, boolean mascara) {
        if (mascara) {
            return Caracter.addMask(imovelServico.getInscricaoCadastral(imovel).replace(",", ""), Caracter.inscricaoCadastralMask);
        }

        return imovelServico.getInscricaoCadastral(imovel).replace(",", "");
    }

    public String mascaraCpfCnpj(Proprietario p) {
        if (p.getTipoDocumento() != null) {
            if (p.getTipoDocumento().equals(TipoDocumento.CPF)) {
                return (p.getCpf() != null && !p.getCpf().isEmpty()) ? Caracter.addMask(p.getCpf(), Caracter.cpfMask) : "";
            } else {
                return (p.getCnpj() != null && !p.getCnpj().isEmpty()) ? Caracter.addMask(p.getCnpj(), Caracter.cnpjMask) : "";
            }
        }

        return "";
    }

    public String getMes(int mes) {

        if (mes < 0 || mes > 12) {
            return null;
        }

        List<String> meses = Arrays.asList("Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro");

        return meses.get(mes);
    }

    public String mes(Date data) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(data);

        return getMes(calendar.get(Calendar.MONTH));
    }

    public String mesAtual() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());

        return getMes(calendar.get(Calendar.MONTH));
    }

    public void atualizarAnexos() {
//        proprietarioServico.copiaAnexos();
//
//        Anexo an;
//        List<Imovel> imoveis = imovelServico.findAll();
//        for (Imovel imovel : imoveis) {
//
//            List<Anexo> anexos = imovelServico.lstAnnexs(imovel);
//            anexos.addAll(imovelServico.lstAnnexCroqui(imovel));
//
//            for (Anexo a : anexos) {
//                an = anexoServico.find(a.getId());
//                an.setUrl(ArquivoUtilitario.REAL_PATH_OPT + Imovel.class.getSimpleName().toLowerCase() + "/" + imovel.getId() + "/");
//                System.err.println(an.getId() + " - " + an.getUrl());
//                anexoServico.update(an);
//            }
//        }
////
//        System.err.println("size = " + imoveis.size());
//
//        List<Aforamento> aforamentos = aforamentoServico.findAll();
//
//        for (Aforamento aforamento : aforamentos) {
//            for (Anexo a : aforamento.getAnexos()) {
//                an = anexoServico.find(a.getId());
//                an.setUrl(ArquivoUtilitario.REAL_PATH_OPT + Aforamento.class.getSimpleName().toLowerCase() + "/" + aforamento.getId() + "/");
//                System.err.println(an.getId() + " - " + an.getUrl());
//                anexoServico.update(an);
//            }
//        }
//
//        System.err.println("size = " + aforamentos.size());
//
//        for (Localidade localidade : localidadeServico.findAll()) {
//            an = anexoServico.find(localidade.getAnexo().getId());
//            an.setUrl(ArquivoUtilitario.REAL_PATH_OPT + Localidade.class.getSimpleName().toLowerCase() + "/" + localidade.getId() + "/");
//            System.err.println(an.getId() + " - " + an.getUrl());
//            anexoServico.update(an);
//        }
//        Prefeitura p = prefeituraServico.find();
//        List<Anexo> anPrefeitura = new ArrayList<Anexo>();
//
//        if (p.getLogo() != null && p.getId() != null) {
//            anPrefeitura.add(anexoServico.find(p.getLogo().getId()));
//        }
//
//        if (p.getLogoRegularizacaoFundiaria() != null && p.getLogoRegularizacaoFundiaria().getId() != null) {
//            anPrefeitura.add(anexoServico.find(p.getLogoRegularizacaoFundiaria().getId()));
//        }
//
//        for (Anexo a : anPrefeitura) {
//            a.setUrl(ArquivoUtilitario.REAL_PATH_OPT + Prefeitura.class.getSimpleName().toLowerCase() + "/" + p.getId() + "/");
//            System.err.println(a.getId() + " - " + a.getUrl());
//            anexoServico.update(a);
//        }
//
//        System.err.println("FIM");
    }
}
